package com.xjrh.traintravel.collector.netty.handler;

import com.xjrh.traintravel.collector.common.CRC16M;
import com.xjrh.traintravel.collector.common.CodeConvertor;
import com.xjrh.traintravel.collector.netty.coder.command.AgreementCommandEnum;
import com.xjrh.traintravel.collector.netty.coder.command.AgreementConstant;
import com.xjrh.traintravel.collector.netty.coder.command.AgreementStructure;
import com.xjrh.traintravel.collector.netty.command.file.FileApply;
import com.xjrh.traintravel.collector.netty.command.file.FileContent;
import com.xjrh.traintravel.collector.netty.command.file.FileInfo;
import com.xjrh.traintravel.collector.netty.command.file.FileList;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author snps
 * @create 2022-02-08 10:17
 * @describe
 **/
@Service
@Slf4j
public class FileHandler extends BaseAgreementHandler {

    /**
     * 发送命令：获取文件列表
     * @param equipmentId 设备标识
     */
    public void getFileList(String equipmentId) {
        AgreementStructure agreement = new AgreementStructure();

        // 前导码(4)
        agreement.setPc(AgreementConstant.PC_VALUE);
        // 帧头(1)
        agreement.setSd(AgreementConstant.SD_VALUE);
        // 控制(1)
        agreement.setFc(AgreementCommandEnum.S_0A.getValue());
        // MAC地址(6)
        agreement.setAddr(equipmentId);
        // 序号(1)
        agreement.setSeq(CodeConvertor.intToHexString(1, 1));
        // 长度(1)
        agreement.setLen(CodeConvertor.intToHexString(1, 2));
        // 数据(N)
        agreement.setData("01");
        // 校验(2)
        String crcValue = CRC16M.calculateCrc(agreement);
        agreement.setFcs(crcValue);
        // 帧尾(1)
        agreement.setFs(AgreementConstant.FS_VALUE);

        super.sendCommand(agreement);
    }

    /**
     * 获取文件列表#回复
     *
     * @param equipmentId
     */
    public void sendGetFileListApply(String equipmentId) {
        AgreementStructure agreement = new AgreementStructure();

        // 前导码(4)
        agreement.setPc(AgreementConstant.PC_VALUE);
        // 帧头(1)
        agreement.setSd(AgreementConstant.SD_VALUE);
        // 控制(1)
        agreement.setFc(AgreementCommandEnum.S_0A.getValue());
        // MAC地址(6)
        agreement.setAddr(equipmentId);
        // 序号(1)
        agreement.setSeq(CodeConvertor.intToHexString(1, 1));
        // 长度(1)
        agreement.setLen(CodeConvertor.intToHexString(2, 2));
        // 数据(N)
        agreement.setData("0201");
        // 校验(2)
        String crcValue = CRC16M.calculateCrc(agreement);
        agreement.setFcs(crcValue);
        // 帧尾(1)
        agreement.setFs(AgreementConstant.FS_VALUE);

        super.sendCommand(agreement);
    }

    /**
     * 得到 文件列表 数据
     * @param equipmentId 设备标识
     * @param data 上报数据
     * @return FileList
     */
    public FileList getFileListData(String equipmentId, String data) {
        FileList fileList = new FileList();
        fileList.setEquipmentId(equipmentId);
        fileList.setCommonNo(data.substring(0, 2));
        fileList.setFileCount(Integer.parseInt(data.substring(2, 6), 16));
        if (fileList.getFileCount() == 0) {
            return fileList;
        }

        fileList.setCurrentNumber(Integer.parseInt(data.substring(6, 10), 16));
        // log.warn("当前传输文件数：{}", fileList.getCurrentNumber());
        fileList.setLastFrame(data.substring(10, 12));
        int startIndex = 12, endIndex = startIndex + 34;
        // log.warn("最后一帧标识：{}", fileList.getLastFrame());

        List<FileInfo> lstFileInfo = new ArrayList<>(fileList.getCurrentNumber());
        for (int i=0; i< fileList.getCurrentNumber(); i++) {
            FileInfo fileInfo = new FileInfo();
            fileInfo.setFileType("1");
            fileInfo.setFileName(CodeConvertor.hexString2String(data.substring(startIndex, endIndex)));
            fileInfo.setFileDesc("a");
            lstFileInfo.add(fileInfo);
            startIndex = endIndex;
            endIndex = startIndex + 34;
        }
        fileList.setFileInfos(lstFileInfo);
        return fileList;
    }


    /**************************************************************************
     * 发送命令：获取文件内容
     * @param equipmentId 设备标识
     * @param fileName 文件名
     */
    public void getFileContent(String equipmentId, String fileName) {
        AgreementStructure agreement = new AgreementStructure();

        // 前导码(4)
        agreement.setPc(AgreementConstant.PC_VALUE);
        // 帧头(1)
        agreement.setSd(AgreementConstant.SD_VALUE);
        // 控制(1)
        agreement.setFc(AgreementCommandEnum.S_OB.getValue());
        // MAC地址(6)
        agreement.setAddr(equipmentId);
        // 序号(1)
        agreement.setSeq(CodeConvertor.intToHexString(1, 1));
        // 长度(2)
        agreement.setLen(CodeConvertor.intToHexString(36, 2));
        // 数据(N)
        agreement.setData("01" + fileName);
        // 校验(2)
        String crcValue = CRC16M.calculateCrc(agreement);
        agreement.setFcs(crcValue);
        // 帧尾(1)
        agreement.setFs(AgreementConstant.FS_VALUE);

        super.sendCommand(agreement);
    }

    /**
     * 得到 获取文件内容#回复
     *
     * @param equipmentId 设备标识
     * @param data 上报数据
     * @return FileApply
     */
    public FileApply getFileContentApply(String equipmentId, String data) {
        FileApply fileApply = new FileApply();
        fileApply.setEquipmentId(equipmentId);
        fileApply.setCommonNo(data.substring(0, 2));
        fileApply.setResult(data.substring(2, 4));
        return fileApply;
    }

    /**
     * 得到 获取文件内容
     *
     * @param equipmentId
     * @param data
     * @return
     */
    public FileContent getFileContentData(String equipmentId, String data) {
        // log.warn("data size: {}", String.valueOf(data.length()));

        FileContent fileContent = new FileContent();
        fileContent.setEquipmentId(equipmentId);
        fileContent.setCommonNo(data.substring(0, 2));
        fileContent.setPackageCount(Integer.parseInt(data.substring(2, 6), 16));
        fileContent.setCurrentPackageNumber(Integer.parseInt(data.substring(6, 10), 16));
        fileContent.setFileContentLength(Integer.parseInt(data.substring(10, 14)));
        fileContent.setFileContent(data.substring(14));
        // log.warn(fileContent.getFileContent());
        // log.warn("fileContent size: {}", String.valueOf(fileContent.getFileContent().length()));

        return fileContent;
    }

    /**
     * 发送命令：回复收到文件内容
     *
     * @param equipmentId
     */
    public void replyGetFileContentData(String equipmentId) {
        AgreementStructure agreement = new AgreementStructure();

        // 前导码(4)
        agreement.setPc(AgreementConstant.PC_VALUE);
        // 帧头(1)
        agreement.setSd(AgreementConstant.SD_VALUE);
        // 控制(1)
        agreement.setFc(AgreementCommandEnum.R_8B.getValue());
        // MAC地址(6)
        agreement.setAddr(equipmentId);
        // 序号(1)
        agreement.setSeq(CodeConvertor.intToHexString(1, 1));
        // 长度(2)
        agreement.setLen(CodeConvertor.intToHexString(2, 2));
        // 数据(N)
        agreement.setData("01" + "01");
        // 校验(2)
        String crcValue = CRC16M.calculateCrc(agreement);
        agreement.setFcs(crcValue);
        // 帧尾(1)
        agreement.setFs(AgreementConstant.FS_VALUE);

        super.sendCommand(agreement);
    }


    /**
     * 发送命令：开始采集数据
     * @param equipmentId 设备标识
     */
    public void collectionDataStart(String equipmentId) {
        AgreementStructure agreement = new AgreementStructure();

        // 前导码(4)
        agreement.setPc(AgreementConstant.PC_VALUE);
        // 帧头(1)
        agreement.setSd(AgreementConstant.SD_VALUE);
        // 控制(1)
        agreement.setFc("AA");
        // MAC地址(6)
        agreement.setAddr(equipmentId);
        // 序号(1)
        agreement.setSeq(CodeConvertor.intToHexString(1, 1));
        // 长度(1)
        agreement.setLen(CodeConvertor.intToHexString(1, 2));
        // 数据(N)
        agreement.setData("01");
        // 校验(2)
        String crcValue = CRC16M.calculateCrc(agreement);
        agreement.setFcs(crcValue);
        // 帧尾(1)
        agreement.setFs(AgreementConstant.FS_VALUE);

        super.sendCommand(agreement);
    }

}